﻿// This code is released under the BSD license.
namespace PugLib.Functional
{
    using System;
    using System.IO;
    using System.Text;

    public static class Continuations
    {
        //public static K<WebResponse> GetResponseAsync(this WebRequest request)
        //{
        //    return send => request.BeginGetResponse(result =>
        //    {
        //        WebResponse response = request.EndGetResponse(result);
        //        send(response);
        //    }, null);
        //}

        public static K<string> ReadToEndAsync(this Stream stream)
        {
            return send =>
                       {
                           byte[] buffer = new byte[1024];
                           StringBuilder sb = new StringBuilder();
                           Func<IAsyncResult> readChunk = null;
                           readChunk = () => stream.BeginRead(buffer, 0, 1024, result =>
                                                                                   {
                                                                                       int read = stream.EndRead(result);
                                                                                       if (read > 0)
                                                                                       {
                                                                                           sb.Append(Encoding.UTF8.GetString(buffer, 0, read));
                                                                                           if (readChunk != null)
                                                                                           {
                                                                                               readChunk();
                                                                                           }
                                                                                       }
                                                                                       else
                                                                                       {
                                                                                           stream.Dispose();
                                                                                           send(sb.ToString());
                                                                                       }
                                                                                   }, null);
                           readChunk();
                       };
        }

        public static Tout Eval<Tin, Tout>(Tin s, Func<Tin, Tout> k)
        {
            return k(s);
        }
    }
}